#!/usr/bin/env python3.9
# coding: utf-8
import sys,getopt
import sys
import json
from struct import *
from socket import *
from blendshapes import blendshapes
import time

"""
主要负责将Audio2Face输出的BlendShapes的
"""

HELP_STRING='send_blendshapes_data.py -f <filePath> -s <server> -p <port>'

def format_jsondata(data,server,port,up):
    """
    将JSON数据转换为对应的格式
    """
    for item in data["weightMat"]:        
        cstruct_data=to_struct(package_blendshape(item))
        #print(cstruct_data)
        time.sleep(0.016)
        send_structto_ue(cstruct_data,server,int(port),up)


def to_struct(send_data):
    """
    将数据封装为C++的结构体
    """
    return pack("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",send_data.eyeblinkleft,send_data.eyelookdownleft,send_data.eyelookinleft,send_data.eyelookoutleft,send_data.eyelookupleft,send_data.eyesquintleft,send_data.eyewideleft,send_data.eyeblinkright,send_data.eyelookdownright,send_data.eyelookinright,send_data.eyelookoutright,send_data.eyelookupright,send_data.eyesquintright,send_data.eyewideright,send_data.jawforward,send_data.jawright,send_data.jawleft,send_data.jawopen,send_data.mouthclose,send_data.mouthfunnel,send_data.mouthpucker,send_data.mouthright,send_data.mouthleft,send_data.mouthsmileleft,send_data.mouthsmileright,send_data.mouthfrownleft,send_data.mouthfrownright,send_data.mouthdimpleleft,send_data.mouthdimpleright,send_data.mouthstretchleft,send_data.mouthstretchright,send_data.mouthrolllower,send_data.mouthrollupper,send_data.mouthshruglower,send_data.mouthshrugupper,send_data.mouthpressleft,send_data.mouthpressright,send_data.mouthlowerdownleft,send_data.mouthlowerdownright,send_data.mouthupperupleft,send_data.mouthupperupright,send_data.browdownleft,send_data.browdownright,send_data.browinnerup,send_data.browouterupleft,send_data.browouterupright,send_data.cheekpuff,send_data.cheeksquintleft,send_data.cheeksquintright,send_data.nosesneerleft,send_data.nosesneerright,send_data.tongueout,send_data.headyaw,send_data.headpitch,send_data.headroll,send_data.lefteyeyaw,send_data.lefteyepitch,send_data.lefteyeroll,send_data.righteyeyaw,send_data.righteyepitch,send_data.righteyeroll,send_data.righteyeroll2)

def package_blendshape(item):
    """
    将Audio2Face的数据包封装成UE插件的数据包
    """
    send_data=None
    if item is not None: 
        send_data=blendshapes()
        send_data.eyeblinkleft=item[0]
        send_data.eyelookdownleft=item[1]
        send_data.eyelookinleft=item[2]
        send_data.eyelookoutleft=item[3]
        send_data.eyelookupleft=item[4]
        send_data.eyesquintleft=item[5]
        send_data.eyewideleft=item[6]
        send_data.eyeblinkright=item[7]
        send_data.eyelookdownright=item[8]
        send_data.eyelookinright=item[9]
        send_data.eyelookoutright=item[10]
        send_data.eyelookupright=item[11]
        send_data.eyesquintright=item[12]
        send_data.eyewideright=item[13]
        send_data.jawforward=item[14]
        send_data.jawright=item[15]
        send_data.jawleft=item[16]
        send_data.jawopen=item[17]
        send_data.mouthclose=item[18]
        send_data.mouthfunnel=item[19]
        send_data.mouthpucker=item[20]
        send_data.mouthright=item[21]
        send_data.mouthleft=item[22]
        send_data.mouthsmileleft=item[23]
        send_data.mouthsmileright=item[24]
        send_data.mouthfrownleft=item[25]
        send_data.mouthfrownright=item[26]
        send_data.mouthdimpleleft=item[27]
        send_data.mouthdimpleright=item[28]
        send_data.mouthstretchleft=item[29]
        send_data.mouthstretchright=item[30]
        send_data.mouthrolllower=item[31]
        send_data.mouthrollupper=item[32]
        send_data.mouthshruglower=item[33]
        send_data.mouthshrugupper=item[34]
        send_data.mouthpressleft=item[35]
        send_data.mouthpressright=item[36]
        send_data.mouthlowerdownleft=item[37]
        send_data.mouthlowerdownright=item[38]
        send_data.mouthupperupleft=item[39]
        send_data.mouthupperupright=item[40]
        send_data.browdownleft=item[41]
        send_data.browdownright=item[42]
        send_data.browinnerup=item[43]
        send_data.browouterupleft=item[44]
        send_data.browouterupright=item[45]
        send_data.cheekpuff=item[46]
        send_data.cheeksquintleft=item[47]
        send_data.cheeksquintright=item[48]
        send_data.nosesneerleft=item[49]
        send_data.nosesneerright=item[50]
        send_data.tongueout=item[51]
        send_data.headyaw=item[52]
        send_data.headpitch=item[53]
        send_data.headroll=item[54]
        send_data.lefteyeyaw=item[55]
        send_data.lefteyepitch=item[56]
        send_data.lefteyeroll=item[57]
        send_data.righteyeyaw=item[58]
        send_data.righteyepitch=item[59]
        send_data.righteyeroll=item[60]
        send_data.righteyeroll2=0.0
    return send_data

def send_structto_ue(item,server,port,up):
    """
    将解析的JSON数据发给UE
    """
    dest_addr = (server,port) 
    up.sendto(item,dest_addr)

def load_json_from_file(path):
    """
    从文件LoadJSON 文件对像进行测试
    """
    with open(path,'r') as f:
        data = json.load(f)
        return data

if __name__ == '__main__':
    file_path=None
    server="172.28.126.151"
    port=8783
    try:
        opts, args = getopt.getopt(sys.argv[1:],"-h-f:-s:-p:",["help","file=","server=","port="])
    except getopt.GetoptError:
        print(HELP_STRING)
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print(HELP_STRING)
            sys.exit()
        elif opt in ("-f", "--file"):
            file_path=arg
        elif opt in ("-s", "--server"):
            server=arg
        elif opt in ("-p", "--port"):
            port=arg    
    if file_path is None:
        print(HELP_STRING)
        sys.exit()
    else:
        print("form data:{} to server:{}:{}".format(file_path,server,port))
        udp_socket = socket(AF_INET, SOCK_DGRAM)        
        data=load_json_from_file(file_path)
        format_jsondata(data,server,port,udp_socket)